package com.zcj.demo.utils;

import com.zcj.demo.user.domain.UserDO;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.spec.SecretKeySpec;
import java.io.Serializable;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author 68300119
 * @Date 2020/10/13
 **/
public class JwtTokenUtil implements Serializable {

    private static final long serialVersionUID = -5291972672506522166L;

    static Key key = new SecretKeySpec("485809BB61274C9181AABAC6048E3E5C".getBytes(),
            SignatureAlgorithm.HS512.getJcaName());

    private static long expiration = 7 * 24 * 3600;

    /**
     * 生成失效时间
     *
     * @param expiration
     * @return
     */
    private static Date generateExpirationDate(long expiration) {
        return new Date(System.currentTimeMillis() + expiration * 1000);
    }


    /***
     * 解析token 信息
     * @param token
     * @return
     */
    private static Claims getClaimsFromToken(String token) {

        if (StringUtils.isEmpty(token)) {
            return null;
        }

        Claims claims;
        try {
            claims = Jwts.parser()
                    //签名的key
                    .setSigningKey(key)
                    // 签名token
                    .parseClaimsJws(token)
                    .getBody();

        } catch (Exception e) {
            claims = null;
        }
        return claims;
    }

    /**
     * 刷新令牌
     *
     * @param token 原令牌
     * @return 新令牌
     */
    public static String refreshToken(String token) {
        String refreshedToken;
        try {
            UserDO userInfo = getUserInfoFromToken(token);
            refreshedToken = generateToken(userInfo);
        } catch (Exception e) {
            refreshedToken = null;
        }
        return refreshedToken;
    }

    /**
     * 根据token 获取Uid
     *
     * @param token
     * @return
     */
    public static UserDO getUserInfoFromToken(String token) {
        try {
            final Claims claims = getClaimsFromToken(token);
            UserDO userInfo = new UserDO();
            userInfo.setId(claims.get("id").toString());
            return userInfo;
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * 生成token
     *
     * @param userInfo
     * @return
     */
    public static String generateToken(UserDO userInfo) {

        String compactJws = Jwts.builder()
                .setId(UUID.randomUUID().toString())
                .setSubject(userInfo.getId())
                .setClaims(generateClaims(userInfo))
                .setIssuedAt(new Date())
                .setExpiration(generateExpirationDate(expiration))
                //密钥
                .signWith(SignatureAlgorithm.HS512, key)
                .compact();

        return compactJws;
    }

    /**
     * 组合用户参数
     *
     * @param user
     * @return
     */
    private static Map<String, Object> generateClaims(UserDO user) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", user.getId());
        return claims;
    }

    /**
     * token 是否过期
     *
     * @param token
     * @return
     */
    public static boolean isTokenExpired(String token) {
        Date expiration;
        try {
            Claims claims = getClaimsFromToken(token);
            expiration = claims.getExpiration();
        } catch (Exception e) {
            expiration = null;
        }

        return expiration.before(new Date());
    }

    /**
     * 验证token 是否合法
     *
     * @param token token
     * @return
     */
    public static Boolean validateToken(String token) {
        return (!isTokenExpired(token));
    }


    public static void main(String[] args) {
        UserDO user = new UserDO();
        user.setId("oJthW43sduzdP9rF2OcbbLd4kivE");
        System.out.println(generateToken(user));
    }
}
